home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / grafica / pvrgjpeg / lexer.l < prev    next >
Text File  |  1999-01-01  |  29KB  |  1,290 lines

  1. /*************************************************************
  2. Copyright (C) 1990, 1991, 1993 Andy C. Hung, all rights reserved.
  3. PUBLIC DOMAIN LICENSE: Stanford University Portable Video Research
  4. Group. If you use this software, you agree to the following: This
  5. program package is purely experimental, and is licensed "as is".
  6. Permission is granted to use, modify, and distribute this program
  7. without charge for any purpose, provided this license/ disclaimer
  8. notice appears in the copies.  No warranty or maintenance is given,
  9. either expressed or implied.  In no event shall the author(s) be
  10. liable to you or a third party for any special, incidental,
  11. consequential, or other damages, arising out of the use or inability
  12. to use the program for any purpose (or the loss of data), even if we
  13. have been advised of such possibilities.  Any public reference or
  14. advertisement of this source code should refer to it as the Portable
  15. Video Research Group (PVRG) code, and not by any author(s) (or
  16. Stanford University) name.
  17. *************************************************************/
  18. %{
  19.  
  20. /*LABEL lexer.c */
  21.  
  22. /* Redefine the yywrap so that we don't have
  23.    to worry about lex library */
  24.  
  25. # define yywrap() (1)
  26.  
  27. static char *ReservedWords[] = {   /* Token names */
  28. "COMPONENT",
  29. "SCAN",
  30. "QUANTIZATION",
  31. "DCSPEC",
  32. "ACCUSTOM",
  33. "DCCUSTOM",
  34. "PRINTSCAN",
  35. "PRINTFRAME",
  36. "PRINTIMAGE",
  37. "OPENSCAN",
  38. "ACSPEC",
  39. "WRITESCAN",
  40. "WRITEFRAME",
  41. "WRITESOI",
  42. "WRITEQUANTIZATION",
  43. "WRITERESYNC",
  44. "WRITEHUFFMAN",
  45. "FREQUENCY",
  46. "ACSEND",
  47. "DCSEND",
  48. "QSEND",
  49. "STREAMNAME",
  50. "IMAGEHEIGHT",
  51. "IMAGEWIDTH",
  52. "RESYNC",
  53. "BUFFER",
  54. "OPENSTREAM",
  55. "CLOSESTREAM",
  56. "FRAMEHEIGHT",
  57. "FRAMEWIDTH",
  58. "CLOSESCAN",
  59. "WRITEEOI",
  60. "ECHO",
  61. "WRITESPECIAL",
  62. "WRITEDIRECT",
  63. "LUMINANCEDEFAULT",
  64. "CHROMINANCEDEFAULT",
  65. "ENABLE",
  66. "SCANDNL",
  67. "WRITEDNL",
  68. "AUTO",
  69. "EMPTY",
  70. ""};
  71.  
  72. #define R_COMPONENT 1           /* Token values mapped to token names */
  73. #define R_SCAN 2
  74. #define R_QUANTIZATION 3
  75. #define R_DCSPEC 4
  76. #define R_ACCUSTOM 5
  77. #define R_DCCUSTOM 6
  78. #define R_PRINTSCAN 7
  79. #define R_PRINTFRAME 8
  80. #define R_PRINTIMAGE 9
  81. #define R_OPENSCAN 10
  82. #define R_ACSPEC 11
  83. #define R_WRITESCAN 12
  84. #define R_WRITEFRAME 13
  85. #define R_WRITESOI 14
  86. #define R_WRITEQUANTIZATION 15
  87. #define R_WRITERESYNC 16
  88. #define R_WRITEHUFFMAN 17
  89. #define R_FREQUENCY 18
  90. #define R_ACSEND 19
  91. #define R_DCSEND 20
  92. #define R_QSEND 21
  93. #define R_STREAMNAME 22
  94. #define R_IMAGEHEIGHT 23
  95. #define R_IMAGEWIDTH 24
  96. #define R_RESYNC 25
  97. #define R_BUFFER 26
  98. #define R_OPENSTREAM 27
  99. #define R_CLOSESTREAM 28
  100. #define R_FRAMEHEIGHT 29
  101. #define R_FRAMEWIDTH 30
  102. #define R_CLOSESCAN 31
  103. #define R_WRITEEOI 32
  104. #define R_ECHO 33
  105. #define R_WRITESPECIAL 34
  106. #define R_WRITEDIRECT 35
  107. #define R_LUMINANCEDEFAULT 36
  108. #define R_CHROMINANCEDEFAULT 37
  109. #define R_ENABLE 38
  110. #define R_SCANDNL 39
  111. #define R_WRITEDNL 40
  112. #define R_AUTO 41
  113. #define R_EMPTY 42
  114.  
  115. #define R_INTEGER 1000      /* Special TYPES for tokens */
  116. #define R_LBRACKET 1001
  117. #define R_RBRACKET 1002
  118. #define R_ID 1003
  119. #define R_STRING 1004
  120.  
  121. int CommentDepth = 0;  /* depth of comment nesting */
  122. int yyint=0;           /* Return value for integers */
  123. int LexDebug=0;        /* Status of lex debugging */
  124.  
  125. #define PRIME 211
  126. #define EOS '\0'
  127.  
  128. #define MakeStructure(S) (S *) malloc(sizeof(S))
  129. #define InsertLink(link,list){\
  130. if(!list){list=link;}else{link->next=list;list=link;}}
  131.  
  132. #define LINK struct link_def
  133. struct id {         /* Default id structure */
  134.   char *name;       /* Key */
  135.   int tokentype;    /* Token type */
  136.   int count;        /* Count of # references */
  137. };
  138.  
  139. LINK {              /* A link for the hash buckets */
  140. struct id *lid;     /* Current id */
  141. LINK *next;         /* Pointer to next id */
  142. };
  143.  
  144. /*PUBLIC*/
  145.  
  146. extern void initparser();
  147. extern void parser();
  148.  
  149. static int hashpjw();
  150. static LINK * MakeLink();
  151. static struct id * enter();
  152. static int getint();
  153. static char * getstr();
  154.  
  155. /*PRIVATE*/
  156.  
  157. /*NOPROTO*/
  158.  
  159. %}
  160.  
  161. Delim        [ \t\n]
  162. WhiteSpace    {Delim}+
  163. Letter          [a-zA-Z]
  164. Digit         [0-9]
  165. HexDigit      ({Digit}|[a-fA-F])
  166. OctalDigit    [0-7]
  167. Id        {Letter}({Letter}|{Digit})*
  168. DecInteger     {Digit}+
  169. HexInteger     0[xX]{HexDigit}+
  170. OctInteger     0[oO]{OctalDigit}+
  171. HexInteger2    {HexDigit}+[Hh]
  172. OctInteger2    {OctalDigit}+[BCObco]
  173. CharInteger      '([^\\]|\\([\n^\n]|{OctalDigit}{1,3}))'
  174. ScaleFactor    E[-+]?{Digit}+
  175. Real1        ({Digit}+"."{Digit}*({ScaleFactor})?)
  176. Real2        ({Digit}*"."{Digit}+({ScaleFactor})?)
  177. Real3        ({Digit}+{ScaleFactor})
  178. Real        {Real1}|{Real2}|{Real3}
  179. Operator     (\+|=|\-|#|\*|\<|\>|\/|:=|\<\>|\&|\<=|\.|\>=|\,|\.\.|;|:|\(|\)|\[|\]|\{|\}|\^|\||~)
  180. String        \"([^\"]|\\\")*\"
  181.  
  182. %S NORMAL COMMENT
  183. %%
  184.  
  185. <NORMAL>{WhiteSpace}    {}
  186.  
  187. <NORMAL>{Id}    {struct id *temp; temp = enter(0,yytext,yyleng); 
  188.          if (LexDebug)
  189.            {
  190.              printf("%s : %s (%d)\n",
  191.                 yytext,
  192.                 ((temp->tokentype) ? "RESERVED" : "IDENTIFIER"),
  193.                 temp->count);
  194.            }
  195.          if (temp->tokentype)
  196.            {
  197.              return(temp->tokentype);
  198.            }
  199.          else
  200.            {
  201.              return(R_ID);
  202.            }
  203.            }
  204. <NORMAL>{Real}            {if (LexDebug)
  205.                {
  206.                  printf("%s : %s\n", yytext, "REAL");
  207.                }
  208.                }
  209. <NORMAL>{DecInteger}    {if (LexDebug)
  210.                {             
  211.                  printf("%s : %s\n", yytext, "INTEGER");
  212.                }
  213.              yyint = atoi(yytext);
  214.              return(R_INTEGER);}
  215. <NORMAL>{HexInteger}    {if (LexDebug)
  216.                {
  217.                  printf("%s : %s\n", yytext, "(HEX)INTEGER");
  218.                }
  219.              yyint = strtol(yytext+2,NULL,16);
  220.              return(R_INTEGER);}
  221. <NORMAL>{HexInteger2}    {if (LexDebug)
  222.                {
  223.                  printf("%s : %s\n", yytext, "(HEX)INTEGER");
  224.                }
  225.              yyint = strtol(yytext,NULL,16);
  226.              return(R_INTEGER);}
  227. <NORMAL>{OctInteger}    {if (LexDebug)
  228.                {
  229.                  printf("%s : %s\n", yytext, "(OCT)INTEGER");
  230.                }
  231.              yyint = strtol(yytext+2,NULL,8);
  232.              return(R_INTEGER);}
  233. <NORMAL>{OctInteger2}    {if (LexDebug)
  234.                {
  235.                  printf("%s : %s\n", yytext, "(OCT)INTEGER");
  236.                }
  237.              yyint = strtol(yytext,NULL,8);
  238.              return(R_INTEGER);}
  239. <NORMAL>{CharInteger}    {if (LexDebug)
  240.                {
  241.                  printf("%s : %s\n", yytext, "(CHAR)INTEGER");
  242.                }
  243.              if (yyleng>4)
  244.                {
  245.                  yyint = strtol(yytext+2,NULL,8);
  246.                }
  247.              else
  248.                {
  249.                  if (*(yytext+1)=='\\')
  250.                    {
  251.                  switch(*(yytext+2))
  252.                    {
  253.                    case '0':
  254.                      yyint=0;
  255.                      break;
  256.                    case 'b':
  257.                      yyint = 0x8;
  258.                      break;
  259.                    case 'i':
  260.                      yyint = 0x9;
  261.                      break;
  262.                    case 'n':
  263.                      yyint = 0xa;
  264.                      break;
  265.                    case 'v':
  266.                      yyint = 0xb;
  267.                      break;
  268.                    case 'f':
  269.                      yyint = 0xc;
  270.                      break;
  271.                    case 'r':
  272.                      yyint = 0xd;
  273.                      break;
  274.                    default:
  275.                      yyint=(*yytext+2);
  276.                      break;
  277.                    }
  278.                    }
  279.                  else
  280.                    {
  281.                  yyint = *(yytext+1);
  282.                    }
  283.                }
  284.              return(R_INTEGER);}
  285. <NORMAL>\[            {if (LexDebug)
  286.                {
  287.                  printf("%s : %s\n", yytext, "LBRACKET");
  288.                }
  289.              return(R_LBRACKET);}
  290. <NORMAL>\]            {if (LexDebug)
  291.                {
  292.                  printf("%s : %s\n", yytext, "RBRACKET");
  293.                }
  294.              return(R_RBRACKET);}
  295. <NORMAL>{Operator}    {if (LexDebug)
  296.                {
  297.                  printf("%s : %s\n", yytext, "OPERATOR");
  298.                }
  299.                }
  300. <NORMAL>{String}    {if (LexDebug)
  301.                {
  302.                  printf("%s : %s\n", yytext, "STRING");
  303.                }
  304.              return(R_STRING);}
  305.  
  306. <NORMAL,COMMENT>"/*"    {CommentDepth++; BEGIN COMMENT;}
  307.  
  308. <COMMENT>"*/"        {CommentDepth--;if(!CommentDepth) BEGIN NORMAL;}
  309.  
  310. <NORMAL>.                {
  311.                   /* None of the above rules applicable, so
  312.                    it's a bad symbol. */
  313.                               printf("Bad input char '%c' on line %d\n",
  314.                             yytext[0],
  315.                             yylineno);
  316.                   }
  317.  
  318. <COMMENT>.|\n        {} /*Everything's AOK */
  319.  
  320. %%
  321.  
  322. /*PROTO*/
  323. LINK *HashTable[PRIME];  /* My little hash table */
  324.  
  325. /*START*/
  326.  
  327. /*BFUNC
  328.  
  329. initparser() is used to place the Reserved Words into the hash table.
  330. It must be called before the parser command is called.
  331.  
  332. EFUNC*/
  333.  
  334. void initparser()
  335. {
  336.   char i,**sptr;
  337.   BEGIN NORMAL;
  338.  
  339.   for(i=1,sptr=ReservedWords;**sptr!='\0';i++,sptr++) 
  340.     {     /* Add Reserved Words */
  341.       enter(i,*sptr,strlen(*sptr));        /* Put reserved words in */
  342.     }                                      /* hash table */
  343. }
  344.  
  345. #undef BEGIN
  346. #undef MakeStructure
  347. #include "globals.h"
  348. #include "stream.h"
  349. #include "tables.h"
  350.  
  351. extern FRAME *CFrame;
  352. extern IMAGE *CImage;
  353. extern SCAN *CScan;
  354. extern int ErrorValue;
  355.  
  356. /*BFUNC
  357.  
  358. hashpjw() returns a hash value for a string input.
  359.  
  360. EFUNC*/
  361.  
  362. static int hashpjw(s)
  363.      char *s;
  364. {
  365.   BEGIN("hashpjw");
  366.   char *p;
  367.   unsigned int h=0,g;
  368.  
  369.   for(p=s;*p!=EOS;p++)       /* Taken from Aho Sethi Ullman Compilers book. */
  370.     {
  371.       h = (h << 4) + *p;
  372.       if (g = h&0xf0000000)
  373.     {
  374.       h = h ^(g >> 24);
  375.       h = h ^ g;
  376.     }
  377.     }
  378.   return(h % PRIME);
  379. }
  380.  
  381. /*BFUNC
  382.  
  383. MakeLink() is used to construct a link object. The link
  384. is used for the hash table construct.
  385.  
  386. EFUNC*/
  387.  
  388.  
  389. static LINK *MakeLink(tokentype,str,len)
  390.      int tokentype;
  391.      char *str;
  392.      int len;
  393. {
  394.   BEGIN("MakeLink");
  395.   LINK *temp;
  396.   
  397.   if (!(temp = MakeStructure(LINK)))            /* Make link */
  398.     {
  399.       WHEREAMI();
  400.       printf("Cannot make a LINK.\n");
  401.       exit(ERROR_MEMORY);
  402.     }
  403.   if (!(temp->lid = MakeStructure(struct id)))  /* Make id */
  404.     {
  405.       printf("Cannot make an id.\n");
  406.       exit(ERROR_MEMORY);
  407.     }
  408.   temp->next = NULL;                            /* Set fields */
  409.   if (!(temp->lid->name =(char *)calloc(len+1,sizeof(char))))
  410.     {
  411.       printf("Cannot make a string space for the link.\n");
  412.       exit(ERROR_MEMORY);
  413.     }
  414.   strcpy(temp->lid->name,str);                 /* Copy key */
  415.   temp->lid->tokentype = tokentype;
  416.   temp->lid->count = 1; 
  417.   return(temp);
  418. }
  419.  
  420. /*BFUNC
  421.  
  422. enter() is used to enter a Reserved Word or ID into the hash table.
  423.  
  424. EFUNC*/
  425.  
  426. static struct id *enter(tokentype,str,len)
  427.      int tokentype;
  428.      char *str;
  429.      int len;
  430. {
  431.   BEGIN("enter");
  432.   int hashnum;
  433.   LINK *temp,*current;
  434.   char *ptr;
  435.  
  436.   for(ptr=str;*ptr!='\0';ptr++)          /* All capitals is fine */
  437.     {
  438.       if ((*ptr>='a') && (*ptr<='z'))
  439.     {
  440.       *ptr = *ptr - ('a'-'A');
  441.     }
  442.     }
  443.   hashnum = hashpjw(str);                /* Check if in hash table */
  444.   for(temp=NULL,current=HashTable[hashnum];
  445.       current!= NULL;
  446.       current=current->next)
  447.     {
  448.       if (strcmp(str,current->lid->name) == 0)
  449.     {
  450.       temp=current;
  451.       break;
  452.     }
  453.     }
  454.   if (temp)                          /* Yes, found ID then return */
  455.     {
  456.       temp->lid->count++;
  457.       return(temp->lid);
  458.     }
  459.   else                              /* Else make our own ID and return that*/
  460.     {
  461.       temp = MakeLink(tokentype,str,len);
  462.       InsertLink(temp,HashTable[hashnum]);
  463.       return(temp->lid);
  464.     }
  465. }
  466.  
  467. /*BFUNC
  468.  
  469. getint() takes an integer from the input.
  470.  
  471. EFUNC*/
  472.  
  473. static int getint()
  474. {
  475.   BEGIN("getint");
  476.   int type;
  477.   if ((type=yylex())!=R_INTEGER)
  478.     {
  479.       printf("Bad input, not integer, '%s' on line %d\n",
  480.          yytext,
  481.          yylineno);
  482.       return(0);
  483.     }
  484.   return(yyint);
  485. }
  486.  
  487. /*BFUNC
  488.  
  489. getstr() gets a string from the input. It copies the string to
  490. temporary storage before it returns the pointer.
  491.  
  492. EFUNC*/
  493.  
  494. static char *getstr()
  495. {
  496.   BEGIN("getstr");
  497.   char *tmp,*ptr,*bptr;
  498.   int i,accum,flag;
  499.   if (yylex() != R_STRING)                      /* Check if string */
  500.     {
  501.       printf("String expected.\n");
  502.       if (!(tmp=(char *) malloc(sizeof(char))))
  503.     {
  504.       WHEREAMI();
  505.       printf("Cannot allocate for null string.\n");
  506.       exit(ERROR_MEMORY);
  507.     }
  508.       *tmp='\0';
  509.       return(tmp);
  510.     }
  511.   if (!(tmp=(char *)calloc(strlen(yytext)+1,sizeof(char)))) /* Make space */
  512.     {
  513.       WHEREAMI();
  514.       printf("Cannot allocate %d string space.\n",yyleng);
  515.       exit(ERROR_MEMORY);
  516.     }
  517.   for(bptr=yytext+1,ptr=tmp;*bptr!='"';bptr++,ptr++)   /* Copy to string */
  518.     {
  519.       if (*bptr=='\\')
  520.     {
  521.       bptr++;
  522.       for(flag=0,accum=0,i=0;i<3;i++)  /* Octal character lookahead */
  523.         {
  524.           if ((*bptr>='0')&&(*bptr<='7'))
  525.         {
  526.           accum = (accum<<3)+(*bptr-'0');
  527.           bptr++;
  528.           flag=1;
  529.         }
  530.           else
  531.         {
  532.           break;
  533.         }
  534.         }
  535.       if (flag)
  536.         {
  537.           bptr--;
  538.           *ptr=accum;
  539.         }
  540.       else                           /* Do conversions, if necessary */
  541.         {
  542.           switch(*(bptr))
  543.         {
  544.         case '0':
  545.           *ptr = 0;
  546.           break;
  547.         case 'b':
  548.           *ptr = 0x8;
  549.           break;
  550.         case 'i':
  551.           *ptr = 0x9;
  552.           break;
  553.         case 'n':
  554.           *ptr = 0xa;
  555.           break;
  556.         case 'v':
  557.           *ptr = 0xb;
  558.           break;
  559.         case 'f':
  560.           *ptr = 0xc;
  561.           break;
  562.         case 'r':
  563.           *ptr = 0xd;
  564.           break;
  565.         default:
  566.           *ptr=(*bptr);
  567.         }
  568.         }
  569.     }
  570.       else
  571.     {
  572.       *ptr = (*bptr);
  573.     }
  574.     }
  575.   *ptr='\0';
  576.   return(tmp);
  577. }
  578.  
  579. /*BFUNC
  580.  
  581. parser() handles all of the parsing required for the Command
  582. Interpreter.  It is basically a while statement with a very large case
  583. statement for every input. The Command Interpreter is essentially
  584. driven by the keywords. All unmatched values such as integers,
  585. strings, and brackets, are ignored.
  586.  
  587. EFUNC*/
  588.  
  589. #define ARRAYBEGIN if (ntoken==R_LBRACKET)\
  590.         {\
  591.           arrayflag=1;\
  592.           ntoken=yylex();\
  593.         }\
  594.       if (ntoken!=R_INTEGER)\
  595.         {\
  596.           WHEREAMI();\
  597.           printf("Expected integer.\n");\
  598.           break;\
  599.         }\
  600.       while(1)\
  601.         {
  602.  
  603. #define ARRAYEND  if (arrayflag)\
  604.         {\
  605.           if ((ntoken=yylex())==R_RBRACKET) break;\
  606.           else if (ntoken!=R_INTEGER)\
  607.             {\
  608.               WHEREAMI();\
  609.               printf("Expected integer or right bracket.\n");\
  610.               break;\
  611.             }\
  612.         }\
  613.           else break;\
  614.           }
  615.  
  616. void parser()
  617. {
  618.   BEGIN("parser");
  619.   int i,dest,value,token,ntoken,arrayflag;
  620.   int accum;
  621.   int Start,End;
  622.   int *ptr,*ptr2;
  623.  
  624.   while(token=yylex())        /* The code handling is simple enough. */
  625.     {                         /* just read the code and documentation */
  626.       ErrorValue=0;           /* book... */
  627.       arrayflag=0;
  628.       switch(token)
  629.     {
  630.     case R_ECHO:
  631.       printf("%s\n",getstr());
  632.       break;
  633.     case R_PRINTIMAGE:
  634.       PrintImage();
  635.       break;
  636.     case R_PRINTFRAME:
  637.       PrintFrame();
  638.       break;
  639.     case R_PRINTSCAN:
  640.       PrintScan();
  641.       break;
  642.     case R_COMPONENT:
  643.       ntoken=yylex();
  644.       ARRAYBEGIN;
  645.       dest = yyint;
  646.       InBounds(dest,0,MAXIMUM_COMPONENTS-1,"Bad component reference");
  647.       if (ErrorValue) break;
  648.       if (yylex()!=R_LBRACKET)
  649.         {
  650.           WHEREAMI();
  651.           printf("Expected left bracket.\n");
  652.           break;
  653.         }
  654.       CFrame->ComponentFileName[dest] = getstr();
  655.       value=getint();
  656.       InBounds(value,0,MAXIMUM_HORIZONTAL_FREQUENCY,
  657.            "Bad horizontal frequency");
  658.       if (ErrorValue) break;
  659.       CFrame->hf[dest]=value;
  660.       value=getint();
  661.       InBounds(value,0,MAXIMUM_VERTICAL_FREQUENCY,
  662.            "Bad vertical frequency");
  663.       if (ErrorValue) break;
  664.       CFrame->vf[dest]=value;
  665.       value=getint();
  666.       InBounds(value,0,MAXIMUM_DEVICES-1,"Bad device reference");
  667.       if (ErrorValue) break;
  668.       CFrame->tq[dest]=value;
  669.       CFrame->cn[CFrame->GlobalNumberComponents++]=dest;/*Know to use it*/
  670.       if (yylex()!=R_RBRACKET)
  671.         {
  672.           WHEREAMI();
  673.           printf("Expected right bracket.\n");
  674.           break;
  675.         }
  676.       ARRAYEND;
  677.       break;
  678.     case R_SCAN:
  679.       CScan->NumberComponents=0;
  680.       ntoken=yylex();
  681.       ARRAYBEGIN;
  682.       if (CScan->NumberComponents>=MAXIMUM_SOURCES)
  683.         {
  684.           WHEREAMI();
  685.           printf("Exceeded number of sources per scan.\n");
  686.           break;
  687.         }
  688.       InBounds(yyint,0,MAXIMUM_COMPONENTS-1,"Bad component reference");
  689.       if (ErrorValue) break;
  690.       for(i=0;i<CFrame->GlobalNumberComponents;i++)  /* Check there */
  691.             if (CFrame->cn[i]==yyint) break;
  692.       if (i==CFrame->GlobalNumberComponents)
  693.         {
  694.           WHEREAMI();
  695.           printf("Scan index not defined in frame yet.\n");
  696.           break;
  697.         }
  698.       CScan->ci[CScan->NumberComponents] = yyint;
  699.       if (yylex()!=R_LBRACKET)
  700.         {
  701.           WHEREAMI();
  702.           printf("Expected left bracket.\n");
  703.           break;
  704.         }
  705.       value=getint();
  706.       InBounds(value,0,MAXIMUM_DEVICES-1,"Bad device reference");
  707.       if (ErrorValue) break;
  708.       CScan->td[CScan->NumberComponents]=value;
  709.       value=getint();
  710.       InBounds(value,0,MAXIMUM_DEVICES-1,"Bad device reference");
  711.       if (ErrorValue) break;
  712.       CScan->ta[CScan->NumberComponents]=value;
  713.       CScan->NumberComponents++;
  714.       if (yylex()!=R_RBRACKET)
  715.         {
  716.           WHEREAMI();
  717.           printf("Expected right bracket.\n");
  718.           break;
  719.         }
  720.       ARRAYEND;
  721.       break;
  722.     case R_QUANTIZATION:
  723.       ntoken=yylex();
  724.       ARRAYBEGIN;
  725.       dest = yyint;
  726.       InBounds(dest,0,MAXIMUM_DEVICES-1,
  727.            "Bad quantization reference.");
  728.       if (ErrorValue) break;
  729.       ntoken=yylex();
  730.       if (ntoken==R_LUMINANCEDEFAULT)
  731.         {
  732.           CImage->QuantizationMatrices[dest]=LuminanceQuantization;
  733.           break;
  734.         }
  735.       else if (ntoken==R_CHROMINANCEDEFAULT)
  736.         {
  737.           CImage->QuantizationMatrices[dest]=ChrominanceQuantization;
  738.           break;
  739.         }
  740.       else if (ntoken!=R_LBRACKET)
  741.         {
  742.           WHEREAMI();
  743.           printf("Expected left bracket.\n");
  744.           break;
  745.         }
  746.       CImage->NumberQuantizationMatrices =
  747.         MAX(CImage->NumberQuantizationMatrices,(dest+1));
  748.       if (!(ptr=(int *)calloc(64,sizeof(int))))
  749.         {
  750.           WHEREAMI();
  751.           printf("Cannot allocate quantization matrix.\n");
  752.           exit(ERROR_MEMORY);
  753.         }
  754.       CImage->NumberQuantizationMatrices =
  755.         MAX(CImage->NumberQuantizationMatrices,(dest+1));
  756.       CImage->QuantizationMatrices[dest]=ptr;
  757.       for(i=0;i<64;i++)
  758.         {
  759.           ptr[i]=16;
  760.         }
  761.       for(i=0;i<65;i++,ptr++) /* One additional to force r-bracket */
  762.         {
  763.           if ((ntoken=yylex())!=R_INTEGER) break;
  764.           InBounds(yyint,1,65535,"Integer out of bounds");
  765.           if (ErrorValue) yyint=16;
  766.           *ptr = yyint;
  767.         }
  768.       if (ntoken!=R_RBRACKET)
  769.         {
  770.           WHEREAMI();
  771.           printf("Expected integer or right bracket.\n");
  772.           break;
  773.         }
  774.       ARRAYEND;
  775.       break;
  776.     case R_ACSEND:
  777.       ntoken=yylex();
  778.       if (ntoken==R_EMPTY)
  779.         {
  780.           CScan->NumberACTablesSend = 0;
  781.           break;
  782.         }
  783.       ARRAYBEGIN;
  784.       if (CScan->NumberACTablesSend>=MAXIMUM_DEVICES)
  785.         {
  786.           WHEREAMI();
  787.           printf("AC Huffman queue full.\n");
  788.           break;
  789.         }
  790.       InBounds(yyint,0,MAXIMUM_DEVICES-1,"Bad device reference");
  791.       if (ErrorValue) break;
  792.       CScan->sa[CScan->NumberACTablesSend++] = yyint;
  793.       ARRAYEND;
  794.       break;
  795.     case R_DCSEND:
  796.       ntoken=yylex();
  797.       if (ntoken==R_EMPTY)
  798.         {
  799.           CScan->NumberDCTablesSend = 0;
  800.           break;
  801.         }
  802.       ARRAYBEGIN;
  803.       if (CScan->NumberDCTablesSend>=MAXIMUM_DEVICES)
  804.         {
  805.           WHEREAMI();
  806.           printf("DC Huffman queue full.\n");
  807.           break;
  808.         }
  809.       InBounds(yyint,0,MAXIMUM_DEVICES-1,"Bad device reference");
  810.       if (ErrorValue) break;
  811.       CScan->sd[CScan->NumberDCTablesSend++] = yyint;
  812.       ARRAYEND;
  813.       break;
  814.     case R_QSEND:
  815.       ntoken=yylex();
  816.       if (ntoken==R_EMPTY)
  817.         {
  818.           CScan->NumberQTablesSend = 0;
  819.           break;
  820.         }
  821.       ARRAYBEGIN;
  822.       if (CScan->NumberQTablesSend>=MAXIMUM_DEVICES)
  823.         {
  824.           WHEREAMI();
  825.           printf("Quantization queue full.\n");
  826.           break;
  827.         }
  828.       InBounds(yyint,0,MAXIMUM_DEVICES-1,"Bad device reference");
  829.       if (ErrorValue) break;
  830.       CScan->sq[CScan->NumberQTablesSend++] = yyint;
  831.       ARRAYEND;
  832.       break;
  833.     case R_STREAMNAME:
  834.       CImage->StreamFileName = getstr();
  835.       break;
  836.     case R_IMAGEWIDTH:
  837.       value=getint();
  838.       InBounds(value,0,MAXIMUM_IMAGE_WIDTH,"Bad image width");
  839.       CFrame->GlobalWidth = value;
  840.       break;
  841.     case R_IMAGEHEIGHT:
  842.       value=getint();
  843.       InBounds(value,0,MAXIMUM_IMAGE_HEIGHT,"Bad image height");
  844.       CFrame->GlobalHeight = value;
  845.       break;
  846.     case R_SCANDNL:
  847.       ntoken=yylex();
  848.       switch(ntoken)
  849.         {
  850.         case R_AUTO:
  851.           CFrame->InsertDnl= -2;
  852.           break;
  853.         case R_ENABLE:
  854.           CFrame->InsertDnl= -1;
  855.           break;
  856.         case R_INTEGER:
  857.           CFrame->InsertDnl = yyint;
  858.           break;
  859.         default:
  860.           WHEREAMI();
  861.           printf("Expected integer.\n");
  862.           break;
  863.         }
  864.       break;
  865.     case R_FRAMEWIDTH:
  866.       ntoken=yylex();
  867.       ARRAYBEGIN;
  868.       dest = yyint;
  869.       InBounds(dest,0,MAXIMUM_COMPONENTS-1,"Bad component destination");
  870.       if (ErrorValue) break;
  871.       value=getint();
  872.       InBounds(value,0,MAXIMUM_IMAGE_WIDTH,"Bad frame width");
  873.       if (ErrorValue) break;
  874.       CFrame->Width[dest] = value;
  875.       ARRAYEND;
  876.       break;
  877.     case R_FRAMEHEIGHT:
  878.       ntoken=yylex();
  879.       ARRAYBEGIN;
  880.       dest = yyint;
  881.       InBounds(dest,0,MAXIMUM_COMPONENTS-1,"Bad component destination");
  882.       if (ErrorValue) break;
  883.       value=getint();
  884.       InBounds(value,0,MAXIMUM_IMAGE_HEIGHT,"Bad frame height");
  885.       if (ErrorValue) break;
  886.       CFrame->Height[dest] = value;
  887.       ARRAYEND;
  888.       break;
  889.     case R_RESYNC:
  890.       value = getint();
  891.       InBounds(value,0,MAXIMUM_RESYNC_INTERVAL,"Bad resync interval");
  892.       if (ErrorValue) break;
  893.       CFrame->ResyncInterval = value;
  894.       break;
  895.     case R_BUFFER:
  896.       value = getint();
  897.       InBounds(value,MINIMUM_BUFFERSIZE,
  898.            MAXIMUM_BUFFERSIZE,"Bad buffersize");
  899.       if (ErrorValue) break;
  900.       CFrame->BufferSize = value;
  901.       break;
  902.     case R_OPENSCAN:
  903.       CheckValidity();
  904.       CheckBaseline();
  905.       ConfirmFileSize();
  906.       MakeIob(IOB_BLOCK,O_RDONLY,1);
  907.       break;
  908.     case R_CLOSESCAN:
  909.       for(i=0;i<CScan->NumberComponents;i++)  /* Close all components */
  910.         {
  911.           InstallIob(i);
  912.           CloseIob();
  913.         }
  914.       break;
  915.     case R_OPENSTREAM:
  916.       if (CImage->StreamFileName)
  917.         {
  918.           swopen(CImage->StreamFileName,0);  /* Index 0 open */
  919.         }
  920.       else
  921.         {
  922.           printf("StreamFileName: Null. Failed\n");
  923.         }
  924.       break;
  925.     case R_CLOSESTREAM:
  926.       swclose();
  927.       break;
  928.     case R_FREQUENCY:
  929.       JpegFrequencyScan();
  930.       break;
  931.     case R_WRITESPECIAL:
  932.       ntoken=yylex();
  933.       ARRAYBEGIN;
  934.       value = yyint;
  935.       swbytealign();
  936.       bputc(0xFF);  /* Marker */
  937.       bputc(value&0xff);
  938.       Start = swtell();
  939.       bputw(0);
  940.       if (yylex()!=R_LBRACKET)
  941.         {
  942.           WHEREAMI();
  943.           printf("Expected left bracket.\n");
  944.           End = swtell();
  945.           swseek(Start);
  946.           bputw((End-Start) >> 3);
  947.           swseek(End);
  948.           break;
  949.         }
  950.       while((ntoken=yylex())==R_INTEGER)
  951.         {
  952.           bputc(yyint&0xff);
  953.         }
  954.       if (ntoken!=R_RBRACKET)
  955.         {
  956.           WHEREAMI();
  957.           printf("Expected integer or right bracket.\n");
  958.           End = swtell();
  959.           swseek(Start);
  960.           bputw((End-Start) >> 3);
  961.           swseek(End);
  962.           break;
  963.         }
  964.       End = swtell();
  965.       swseek(Start);
  966.       bputw((End-Start) >> 3);
  967.       swseek(End);
  968.       ARRAYEND;
  969.       break;
  970.     case R_WRITEDIRECT:
  971.       swbytealign();
  972.       if (yylex()!=R_LBRACKET)
  973.         {
  974.           WHEREAMI();
  975.           printf("Expected left bracket.\n");
  976.           break;
  977.         }
  978.       while((ntoken=yylex())==R_INTEGER)
  979.         {
  980.           bputc(yyint&0xff);
  981.         }
  982.       if (ntoken!=R_RBRACKET)
  983.         {
  984.           WHEREAMI();
  985.           printf("Expected integer or right bracket.\n");
  986.           break;
  987.         }
  988.       break;
  989.     case R_WRITESCAN:
  990.       JpegEncodeScan();
  991.       break;
  992.     case R_WRITEFRAME:
  993.       MakeConsistentFrameSize();  /* Do it here when everything defined */
  994.       WriteSof();
  995.       break;
  996.     case R_WRITESOI:
  997.       WriteSoi();
  998.       break;
  999.     case R_WRITEEOI:
  1000.       WriteEoi();
  1001.       break;
  1002.     case R_WRITEQUANTIZATION:
  1003.       WriteDqt();
  1004.       break;
  1005.     case R_WRITERESYNC:
  1006.       WriteDri();
  1007.       break;
  1008.     case R_WRITEDNL:
  1009.       WriteDnl();
  1010.       break;
  1011.     case R_WRITEHUFFMAN:
  1012.       WriteDht();
  1013.       break;
  1014.     case R_ACCUSTOM:
  1015.       ntoken=yylex();
  1016.       ARRAYBEGIN;
  1017.       dest = yyint;
  1018.       InBounds(dest,0,MAXIMUM_DEVICES-1,"Bad device reference");
  1019.       if (ErrorValue) break;
  1020.       if (yylex()!=R_LBRACKET)
  1021.         {
  1022.           WHEREAMI();
  1023.           printf("Expected left bracket.\n");
  1024.           break;
  1025.         }
  1026.       MakeXhuff();
  1027.       MakeEhuff();
  1028.       if (!(ptr=(int *)calloc(257,sizeof(int))))
  1029.         {
  1030.           WHEREAMI();
  1031.           printf("Out of custom frequency space.\n");
  1032.           exit(ERROR_MEMORY);
  1033.         }
  1034.       for(i=0;i<257;i++)
  1035.         {
  1036.           ptr[i]=0;
  1037.         }
  1038.       while((ntoken=yylex())==R_INTEGER)
  1039.         {
  1040.           InBounds(yyint,0,MAXIMUM_SOURCES-1,"Bad frequency reference");
  1041.           if(ErrorValue) yyint=0;
  1042.           AddFrequency(ptr,CScan->ACFrequency[yyint]);
  1043.         }
  1044.       if (ntoken!=R_RBRACKET)
  1045.         {
  1046.           WHEREAMI();
  1047.           printf("Expected right bracket.\n");
  1048.           break;
  1049.         }
  1050.       MakeHuffman(ptr);
  1051.       SetACHuffman(dest);
  1052.       CImage->NumberACTables = 
  1053.         MAX(CImage->NumberACTables,(dest+1));
  1054.       ARRAYEND;
  1055.       break;
  1056.     case R_DCCUSTOM:
  1057.       ntoken=yylex();
  1058.       ARRAYBEGIN;
  1059.       dest = yyint;
  1060.       InBounds(dest,0,MAXIMUM_DEVICES-1,"Bad device reference");
  1061.       if (ErrorValue) break;
  1062.       if (yylex()!=R_LBRACKET)
  1063.         {
  1064.           WHEREAMI();
  1065.           printf("Expected left bracket.\n");
  1066.           break;
  1067.         }
  1068.       MakeXhuff();
  1069.       MakeEhuff();
  1070.       if (!(ptr=(int *)calloc(257,sizeof(int))))
  1071.         {
  1072.           WHEREAMI();
  1073.           printf("Out of custom frequency space.\n");
  1074.           exit(ERROR_MEMORY);
  1075.         }
  1076.       for(i=0;i<257;i++)
  1077.         {
  1078.           ptr[i]=0;
  1079.         }
  1080.       while((ntoken=yylex())==R_INTEGER)
  1081.         {
  1082.           InBounds(yyint,0,MAXIMUM_SOURCES-1,"Bad frequency reference");
  1083.           if(ErrorValue) yyint=0;
  1084.           AddFrequency(ptr,CScan->DCFrequency[yyint]);
  1085.         }
  1086.       if (ntoken!=R_RBRACKET)
  1087.         {
  1088.           WHEREAMI();
  1089.           printf("Expected right bracket.\n");
  1090.           break;
  1091.         }
  1092.       MakeHuffman(ptr);
  1093.       SetDCHuffman(dest);
  1094.       CImage->NumberDCTables = 
  1095.         MAX(CImage->NumberDCTables,(dest+1));
  1096.       ARRAYEND;
  1097.       break;
  1098.     case R_ACSPEC:
  1099.       ntoken=yylex();
  1100.       ARRAYBEGIN;
  1101.       dest = yyint;
  1102.       InBounds(dest,0,MAXIMUM_DEVICES-1,"Bad device reference");
  1103.       if (ErrorValue) break;
  1104.       MakeXhuff();
  1105.       MakeEhuff();
  1106.       if ((ntoken=yylex())==R_LBRACKET)
  1107.         {
  1108.           if (!(ptr=(int *)calloc(38,sizeof(int)))) /* Get bits */
  1109.         {
  1110.           WHEREAMI();
  1111.           printf("Out of custom bits space.\n");
  1112.           exit(ERROR_MEMORY);
  1113.         }
  1114.           for(i=0;i<32;i++)
  1115.         {
  1116.           ptr[i]=0;
  1117.         }
  1118.           for(accum=0,i=0;i<17;i++) /* First index is bitlength of 1. */
  1119.         {                 /* One additional to force r-bracket. */
  1120.           ntoken=yylex();
  1121.           if (ntoken==R_INTEGER)
  1122.             {
  1123.               accum+=yyint;
  1124.               ptr[i]=yyint;
  1125.             }
  1126.           else break;
  1127.         }
  1128.           if (ntoken!=R_RBRACKET)
  1129.         {
  1130.           WHEREAMI();
  1131.           printf("Expected integer or right bracket.\n");
  1132.           break;
  1133.         }
  1134.           if (yylex()!=R_LBRACKET)  /* Get values */
  1135.         {
  1136.           WHEREAMI();
  1137.           printf("Expected left bracket.\n");
  1138.           break;
  1139.         }
  1140.           if (!(ptr2=(int *)calloc(257,sizeof(int))))
  1141.         {
  1142.           WHEREAMI();
  1143.           printf("Out of custom Huffman value space.\n");
  1144.           exit(ERROR_MEMORY);
  1145.         }
  1146.           for(i=0;i<257;i++)
  1147.         {
  1148.           ptr2[i]=0;
  1149.         }
  1150.           for(i=0;i<257;i++) /* One additinal to force r-bracket */
  1151.         {
  1152.           ntoken=yylex();
  1153.           if (ntoken==R_INTEGER)
  1154.             {
  1155.               ptr2[i]=yyint;
  1156.             }
  1157.           else break;
  1158.         }
  1159.           if (i!=accum)
  1160.         {
  1161.           WHEREAMI();
  1162.           printf("Number of bitlengths != number of values.");
  1163.         }
  1164.           if (ntoken!=R_RBRACKET)
  1165.         {
  1166.           WHEREAMI();
  1167.           printf("Expected integer or right bracket.\n");
  1168.           break;
  1169.         }
  1170.           SpecifiedHuffman(ptr,ptr2);
  1171.         }
  1172.       else if (ntoken==R_CHROMINANCEDEFAULT)
  1173.         {
  1174.           SpecifiedHuffman(ChrominanceACBits,ChrominanceACValues);
  1175.         }
  1176.       else if (ntoken==R_LUMINANCEDEFAULT)
  1177.         {
  1178.           SpecifiedHuffman(LuminanceACBits,LuminanceACValues);
  1179.         }
  1180.       else
  1181.         {
  1182.           WHEREAMI();
  1183.           printf("Expected left bracket or ACDEFAULT.\n");
  1184.           break;
  1185.         }
  1186.       SetACHuffman(dest);
  1187.       CImage->NumberACTables = 
  1188.         MAX(CImage->NumberACTables,(dest+1));
  1189.       ARRAYEND;
  1190.       break;
  1191.     case R_DCSPEC:
  1192.       ntoken=yylex();
  1193.       ARRAYBEGIN;
  1194.       dest = yyint;
  1195.       InBounds(dest,0,MAXIMUM_DEVICES-1,"Bad device reference");
  1196.       if (ErrorValue) break;
  1197.       MakeXhuff();
  1198.       MakeEhuff();
  1199.       if ((ntoken=yylex())==R_LBRACKET)
  1200.         {
  1201.           if (!(ptr=(int *)calloc(38,sizeof(int)))) /* Get bits */
  1202.         {
  1203.           WHEREAMI();
  1204.           printf("Out of custom bits space.\n");
  1205.           exit(ERROR_MEMORY);
  1206.         }
  1207.           for(i=0;i<32;i++)
  1208.         {
  1209.           ptr[i]=0;
  1210.         }
  1211.           for(accum=0,i=0;i<17;i++) /* First index is bitlength of 1. */
  1212.         {                /* 0-16 to force right bracket. */
  1213.           ntoken=yylex();
  1214.           if (ntoken==R_INTEGER)
  1215.             {
  1216.               accum+=yyint;
  1217.               ptr[i]=yyint;
  1218.             }
  1219.           else break;
  1220.         }
  1221.           if (ntoken!=R_RBRACKET)
  1222.         {
  1223.           WHEREAMI();
  1224.           printf("Expected integer or right bracket.\n");
  1225.           break;
  1226.         }
  1227.           if (yylex()!=R_LBRACKET)  /* Get values */
  1228.         {
  1229.           WHEREAMI();
  1230.           printf("Expected left bracket.\n");
  1231.           break;
  1232.         }
  1233.           if (!(ptr2=(int *)calloc(257,sizeof(int))))
  1234.         {
  1235.           WHEREAMI();
  1236.           printf("Out of custom Huffman value space.\n");
  1237.           exit(ERROR_MEMORY);
  1238.         }
  1239.           for(i=0;i<257;i++)
  1240.         {
  1241.           ptr2[i]=0;
  1242.         }
  1243.           for(i=0;i<257;i++) /*One additional to force r-bracket.*/
  1244.         {
  1245.           ntoken=yylex();
  1246.           if (ntoken==R_INTEGER)
  1247.             {
  1248.               ptr2[i]=yyint;
  1249.             }
  1250.           else break;
  1251.         }
  1252.           if (i!=accum)
  1253.         {
  1254.           WHEREAMI();
  1255.           printf("Number of bitlengths != number of values.");
  1256.         }
  1257.           if (ntoken!=R_RBRACKET)
  1258.         {
  1259.           WHEREAMI();
  1260.           printf("Expected integer or right bracket.\n");
  1261.           break;
  1262.         }
  1263.           SpecifiedHuffman(ptr,ptr2);
  1264.         }
  1265.       else if (ntoken==R_CHROMINANCEDEFAULT)
  1266.         {
  1267.           SpecifiedHuffman(ChrominanceDCBits,ChrominanceDCValues);
  1268.         }
  1269.       else if (ntoken==R_LUMINANCEDEFAULT)
  1270.         {
  1271.           SpecifiedHuffman(LuminanceDCBits,LuminanceDCValues);
  1272.         }
  1273.       else
  1274.         {
  1275.           WHEREAMI();
  1276.           printf("Expected left bracket or DCDEFAULT.\n");
  1277.           break;
  1278.         }
  1279.       SetDCHuffman(dest);
  1280.       CImage->NumberDCTables = 
  1281.         MAX(CImage->NumberDCTables,(dest+1));
  1282.       ARRAYEND;
  1283.       break;
  1284.     }
  1285.     }
  1286. }
  1287.  
  1288. /*NOPROTO*/
  1289. /*END*/
  1290.